home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Magazine / C_Tutorial / Part-3 / gadgets1.c < prev    next >
C/C++ Source or Header  |  1997-07-27  |  8KB  |  284 lines

  1. #include<exec/libraries.h>
  2. #include<intuition/intuition.h>
  3. #include<utility/tagitem.h>
  4. #include<graphics/text.h>
  5. #include<graphics/rastport.h>
  6. #include<intuition/screens.h>
  7. #include<libraries/gadtools.h>
  8.  
  9. #include<string.h>
  10. #include<stdio.h>
  11.  
  12. #include<clib/exec_protos.h>
  13. #include<clib/graphics_protos.h>
  14. #include<clib/intuition_protos.h>
  15. #include<clib/layers_protos.h>
  16. #include<clib/gadtools_protos.h>
  17.  
  18. /* The library base global variables */
  19. /* (The different style of opening libraries requires these to be initialised to NULL) */
  20. struct Library* GfxBase = NULL;
  21. struct Library* IntuitionBase = NULL;
  22. struct Library* LayersBase = NULL;
  23. struct Library* GadToolsBase = NULL;
  24.  
  25. /* Need to give prototypes for our functions */
  26. void handleIDCMP(struct Window*);
  27. int setClip(struct Window*);
  28. void removeClip(struct Window*);
  29. void setupWindow();
  30. void createWindow(struct Gadget*);
  31. int openLibs();
  32. void closeLibs();
  33.  
  34. /* Some constants for the size of the window */
  35. #define MYWIN_WIDTH        (400)
  36. #define MYWIN_HEIGHT    (200)
  37.  
  38. /* Some constants for the position and size of our gadget */
  39. #define MYGAD_LEFT        (10)
  40. #define MYGAD_TOP            (5)
  41. #define MYGAD_WIDTH        (80)
  42. #define MYGAD_HEIGHT    (12)
  43. #define MYGAD_TEXT        "Next Pen"
  44. #define MYGAD_ID            (0)
  45.  
  46. /* The top gap required around the gadgets */
  47. #define MYTOPGAP      (30)
  48.  
  49. /* The start of the program */
  50. void main()
  51. {
  52.     /* Use a different style of opening libraries... */
  53.     if(openLibs())
  54.     {
  55.         /* Now do the real work */
  56.         setupWindow();
  57.     }
  58.     /* Matched call to close libraries */
  59.     closeLibs();
  60. }
  61.  
  62. /* Try to open all the libraries -- return TRUE on success */
  63. int openLibs()
  64. {
  65.     if((GfxBase = OpenLibrary("graphics.library",37)) == NULL)
  66.     {
  67.         printf("Error: could not open graphics.library\n");
  68.         return FALSE;
  69.     }
  70.     if((IntuitionBase = OpenLibrary("intuition.library",37)) == NULL)
  71.     {
  72.         printf("Error: could not open intuition.library\n");
  73.         return FALSE;
  74.     }
  75.     if((LayersBase = OpenLibrary("layers.library",37)) == NULL)
  76.     {
  77.         printf("Error: could not open layers.library\n");
  78.         return FALSE;
  79.     }
  80.     if((GadToolsBase = OpenLibrary("gadtools.library",37)) == NULL)
  81.     {
  82.         printf("Error: could not open gadtools.library\n");
  83.         return FALSE;
  84.     }
  85.   return TRUE;
  86. }
  87.  
  88. /* Close any open library */
  89. void closeLibs()
  90. {
  91.     if(GadToolsBase)
  92.         CloseLibrary(GadToolsBase);
  93.     if(LayersBase)
  94.         CloseLibrary(LayersBase);
  95.     if(IntuitionBase)
  96.         CloseLibrary(IntuitionBase);
  97.     if(GfxBase)
  98.         CloseLibrary(GfxBase);
  99. }
  100.  
  101. /* Setup the window -- do the GadTools stuff */
  102. void setupWindow()
  103. {
  104.     struct Screen* scr;
  105.     /* We'll copy the visual information for the default public screen */
  106.   /* (usually, this is the Workbench screen) */
  107.     if(scr = LockPubScreen(NULL))
  108.     {
  109.         APTR vinfo;
  110.         /* Get the visual info so GadTools can render the gadgets nicely */
  111.         if(vinfo = GetVisualInfo(scr, TAG_DONE))
  112.         {
  113.             /* We can initialise glist in its declaration */
  114.             struct Gadget* glist = NULL;
  115.             struct Gadget* gad;
  116.             int offtop, offleft;
  117.             struct NewGadget newgad;
  118.             /* Initialised structure declaration: describes 8pt Topaz font */
  119.             struct TextAttr topazFont = { "topaz.font", 8, 0, 0, };
  120.             /* Start a GadTools gadget list */
  121.             /* (Don't need to check gad, since CreateGadget() will fail if gad is NULL) */
  122.             gad = CreateContext(&glist);
  123.             /* The offsets of our window borders */
  124.             offleft = scr->WBorLeft;
  125.             offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
  126.             /* Setup our first gadget */
  127.             newgad.ng_TextAttr         = &topazFont;
  128.             newgad.ng_VisualInfo     = vinfo;
  129.             newgad.ng_LeftEdge         = MYGAD_LEFT + offleft;
  130.             newgad.ng_TopEdge         = MYGAD_TOP + offtop;
  131.             newgad.ng_Width             = MYGAD_WIDTH;
  132.             newgad.ng_Height             = MYGAD_HEIGHT;
  133.             newgad.ng_GadgetText    = MYGAD_TEXT;
  134.             newgad.ng_GadgetID        = MYGAD_ID;
  135.             newgad.ng_Flags                = 0;
  136.             /* Now create it and add it to our list */
  137.             if(gad = CreateGadget(BUTTON_KIND, gad, &newgad, TAG_DONE))
  138.                 createWindow(glist);
  139.             else
  140.                 printf("Error: could not create gadget(s)\n");
  141.             /* Free the gadget */
  142.             FreeGadgets(glist);
  143.             FreeVisualInfo(vinfo);
  144.         }
  145.         else
  146.             printf("Error: could not get visual info\n");
  147.         UnlockPubScreen(NULL, scr);
  148.     }
  149.     else
  150.         printf("Error: could not lock public screen\n");
  151. }
  152.  
  153. /* Actually open the window, in the normal way */
  154. void createWindow(struct Gadget* glist)
  155. {
  156.     struct Window* win;
  157.     /* Open our window */
  158.     if(win = OpenWindowTags(NULL,
  159.                                                     WA_Width,        MYWIN_WIDTH,
  160.                                                     WA_Height,    MYWIN_HEIGHT,
  161.                                                     WA_Flags,        WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_REPORTMOUSE,
  162.                                                     WA_IDCMP,        IDCMP_CLOSEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | BUTTONIDCMP | IDCMP_REFRESHWINDOW,
  163.                                                     WA_Gadgets,    glist,
  164.                                                     TAG_DONE,        0))
  165.     {
  166.         /* If window opened, set clip region */
  167.         if(setClip(win))
  168.         {
  169.             /* Let GadTools refresh its bits of the window */
  170.             GT_RefreshWindow(win, NULL);
  171.             /* Now handle messages */
  172.             handleIDCMP(win);
  173.             removeClip(win);
  174.         }
  175.         else
  176.             printf("Error: could not set clip region on window\n");
  177.         CloseWindow(win);
  178.     }
  179.     else
  180.         printf("Error: could not open window\n");
  181. }
  182.  
  183. /* Our message handling code */
  184. void handleIDCMP(struct Window* win)
  185. {
  186.     char* text = "Hello World!";
  187.     int going = TRUE;
  188.     int drawing = FALSE;
  189.     UBYTE pen = 1;
  190.     SetAPen(win->RPort, pen);
  191.     /* Set the drawing mode to draw only the foreground of text, not the background */
  192.     SetDrMd(win->RPort, JAM1);
  193.     while(going)
  194.     {
  195.         struct IntuiMessage* intuimsg;
  196.         /* Wait for messages to arrive */
  197.         WaitPort(win->UserPort);
  198.         /* Messages have arrived: loop through all of them */
  199.         while(intuimsg = GT_GetIMsg(win->UserPort))
  200.         {
  201.             /* Act on this message... */
  202.             switch(intuimsg->Class)
  203.             {
  204.             case IDCMP_MOUSEBUTTONS:
  205.                 switch(intuimsg->Code)
  206.                 {
  207.                 case SELECTDOWN:
  208.                     drawing = TRUE;
  209.                     break;
  210.                 case SELECTUP:
  211.                     drawing = FALSE;
  212.                     break;
  213.                 }
  214.                 /* break; omitted so we draw on click, too */
  215.             case IDCMP_MOUSEMOVE:
  216.                 /* Don't draw on top gap which holds gadget */
  217.                 if(drawing && intuimsg->MouseY > win->BorderTop+MYTOPGAP)
  218.                 {
  219.                     Move(win->RPort, intuimsg->MouseX, intuimsg->MouseY);
  220.                     Text(win->RPort, text, strlen(text));
  221.                 }
  222.                 break;
  223.             case IDCMP_CLOSEWINDOW:
  224.                 going = FALSE;
  225.                 break;
  226.             case IDCMP_REFRESHWINDOW:
  227.                 /* You *MUST* remember to ask for and handle these refresh messages */
  228.                 GT_BeginRefresh(win);
  229.                 GT_EndRefresh(win, TRUE);
  230.                 break;
  231.             case IDCMP_GADGETUP:
  232.                 /* Our button was clicked!  Set foreground to next pen colour */
  233.                 pen++;
  234.                 SetAPen(win->RPort, pen);
  235.                 break;
  236.             }
  237.             /* Reply when finished with message */
  238.             GT_ReplyIMsg(intuimsg);
  239.         }
  240.     }
  241. }
  242.  
  243. /* Set a clip region on internal part of window */
  244. int setClip(struct Window* win)
  245. {
  246.     /* Make a new region */
  247.     struct Region* reg;
  248.     if(reg = NewRegion())
  249.     {
  250.         /* Make a rectangle that describes the inside of the window */
  251.         struct Rectangle rect;
  252.         rect.MinX = win->BorderLeft;
  253.         rect.MinY = win->BorderTop;
  254.         rect.MaxX = win->Width - win->BorderRight - 1;
  255.         rect.MaxY = win->Height - win->BorderBottom - 1;
  256.         /* Make the region equal to this rectangle */
  257.         if(OrRectRegion(reg, &rect))
  258.         {
  259.             /* Set the clip region on the window's layer */
  260.             InstallClipRegion(win->WLayer, reg);
  261.             /* Say we succeeded */
  262.             return TRUE;
  263.         }
  264.         else
  265.         {
  266.             /* Failed to set region, so delete it */
  267.             DisposeRegion(reg);
  268.         }
  269.     }
  270.     /* If we get this far they we've failed */
  271.     return FALSE;
  272. }
  273.  
  274. /* Remove the clip region from a window */
  275. void removeClip(struct Window* win)
  276. {
  277.     struct Region* reg;
  278.     if(reg = InstallClipRegion(win->WLayer, NULL))
  279.     {
  280.         /* If a clip region is installed it's our new one, so delete it */
  281.         DisposeRegion(reg);
  282.     }
  283. }
  284.